/////////////////////////////////////////////////////////////////////////////
// This file is part of the "Java-DAP" project, a Java implementation
// of the OPeNDAP Data Access Protocol.
//
// Copyright (c) 2007 OPeNDAP, Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
/////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections;

namespace NDODS.Util
{
    /// <summary> SortedTable looks exactly like Hashtable but preserves the insertion order
    /// of elements.  While this results in slower performance, it ensures that
    /// the DAS will always be printed in the same order in which it was Read.
    /// </summary>
    [Serializable]
    public sealed class SortedTable : IDictionary
    {
        /// <summary> Returns the value to which the key is mapped in this table.
        /// 
        /// </summary>
        /// <param name="key">a key in this table.
        /// </param>
        /// <returns> the value to which the key is mapped, or null if the key is not
        /// mapped to any value in the table.
        /// </returns>
        //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        public Object this[Object key] {
            get {
                int index = keys_Renamed_Field.IndexOf(key);
                if (index != - 1)
                    return elements_Renamed_Field[index];
                else
                    return null;
            }

            set { }
        }

        /// <summary>Returns a Vector containing the elements in the SortedTable.  This is
        /// used for more efficient implementation of NDODS.DAP.Util.UniqueNames() by
        /// NDODS.DAP.DDS.CheckSemantics()
        /// </summary>
        /// <returns> A Vector containing the elements in this SortedTable.
        /// </returns>
        public ArrayList ElementVector {
            get { return elements_Renamed_Field; }
        }

        internal const long serialVersionUID = 1;

        private ArrayList keys_Renamed_Field, elements_Renamed_Field;

        public SortedTable() {
            keys_Renamed_Field = ArrayList.Synchronized(new ArrayList(10));
            elements_Renamed_Field = ArrayList.Synchronized(new ArrayList(10));
        }

        /// <summary> Returns the number of keys in this table.</summary>
        //UPGRADE_NOTE: The equivalent of method 'java.util.Dictionary.size' is not an override method. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1143'"
        public int size() {
            return keys_Renamed_Field.Count;
        }

        /// <summary> Tests if this table is empty.</summary>
        //UPGRADE_NOTE: The equivalent of method 'java.util.Dictionary.isEmpty' is not an override method. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1143'"
        public bool isEmpty() {
            return (keys_Renamed_Field.Count == 0);
        }

        /// <summary> Returns an enumeration of the keys in this table.</summary>
        //UPGRADE_NOTE: The equivalent of method 'java.util.Dictionary.keys' is not an override method. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1143'"
        public ArrayList keys() {
            return keys_Renamed_Field;
        }

        /// <summary> Returns an enumeration of the values in this table.</summary>
        //UPGRADE_NOTE: The equivalent of method 'java.util.Dictionary.elements' is not an override method. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1143'"
        public IEnumerator elements() {
            return elements_Renamed_Field.GetEnumerator();
        }

        /// <summary> Returns the key at the specified index.
        /// 
        /// </summary>
        /// <param name="index">the index to return
        /// </param>
        /// <returns> the key at the specified index.
        /// </returns>
        //UPGRADE_NOTE: Synchronized keyword was removed from method 'getKey'. Lock expression was added. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1027'"
        public Object getKey(int index) {
            lock (this) {
                return keys_Renamed_Field[index];
            }
        }

        /// <summary> Returns the element at the specified index.
        /// 
        /// </summary>
        /// <param name="index">the index to return
        /// </param>
        /// <returns> the element at the specified index.
        /// </returns>
        //UPGRADE_NOTE: Synchronized keyword was removed from method 'elementAt'. Lock expression was added. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1027'"
        public Object elementAt(int index) {
            lock (this) {
                return elements_Renamed_Field[index];
            }
        }

        /// <summary> Maps the specified key to the specified value in this table.
        /// 
        /// </summary>
        /// <param name="key">  the key
        /// </param>
        /// <param name="value_Renamed">the value
        /// </param>
        /// <returns> the previous value to which the key is mapped, or null if the
        /// key did not have a previous mapping.
        /// </returns>
        /// <throws>  NullPointerException if the key or value is null. </throws>
        //UPGRADE_NOTE: The equivalent of method 'java.util.Dictionary.put' is not an override method. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1143'"
        //UPGRADE_NOTE: Synchronized keyword was removed from method 'put'. Lock expression was added. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1027'"
        public Object put(Object key, Object value_Renamed) {
            lock (this) {
                if (key == null || value_Renamed == null)
                    throw new NullReferenceException();

                int index = keys_Renamed_Field.IndexOf(key);
                if (index != - 1) {
                    Object prev = elements_Renamed_Field[index];
                    elements_Renamed_Field[index] = value_Renamed;
                    return prev;
                }
                else {
                    keys_Renamed_Field.Add(key);
                    elements_Renamed_Field.Add(value_Renamed);
                    return null;
                }
            }
        }

        /// <summary> Removes the key (and its corresponding value) from this table.  If the
        /// key is not in the table, do nothing.
        /// 
        /// </summary>
        /// <param name="key">the key to remove.
        /// </param>
        /// <returns> the value to which the key had been mapped, or null if the key
        /// did not have a mapping.
        /// </returns>
        //UPGRADE_NOTE: The equivalent of method 'java.util.Dictionary.remove' is not an override method. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1143'"
        //UPGRADE_NOTE: Synchronized keyword was removed from method 'remove'. Lock expression was added. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1027'"
        public Object remove(Object key) {
            lock (this) {
                int index = keys_Renamed_Field.IndexOf(key);
                if (index != - 1) {
                    Object prev = elements_Renamed_Field[index];
                    keys_Renamed_Field.RemoveAt(index);
                    elements_Renamed_Field.RemoveAt(index);
                    return prev;
                }
                else {
                    return null;
                }
            }
        }

        //UPGRADE_TODO: The following method was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        public Boolean Contains(Object key) {
            return false;
        }

        //UPGRADE_TODO: The following method was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        public void Add(Object key, Object value) {}
        //UPGRADE_TODO: The following method was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        public void Clear() {}
        //UPGRADE_TODO: The following method was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        IDictionaryEnumerator IDictionary.GetEnumerator() {
            return null;
        }

        //UPGRADE_TODO: The following method was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        public void Remove(Object key) {}
        //UPGRADE_NOTE: The following method implementation was automatically added to preserve functionality. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1306'"
        public void CopyTo(Array array, Int32 index) {
            Object[] keys = new Object[this.Count];
            Object[] values = new Object[this.Count];
            if (this.Keys != null)
                this.Keys.CopyTo(keys, index);
            if (this.Values != null)
                this.Values.CopyTo(values, index);
            for (int i = index; i < this.Count; i++)
                if (keys[i] != null || values[i] != null)
                    array.SetValue(new DictionaryEntry(keys[i], values[i]), i);
        }

        //UPGRADE_TODO: The following method was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        IEnumerator IEnumerable.GetEnumerator() {
            return null;
        }

        //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        public ICollection Keys {
            get { return null; }
        }

        //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        public ICollection Values {
            get { return null; }
        }

        //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        public Boolean IsReadOnly {
            get { return false; }
        }

        //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        public Boolean IsFixedSize {
            get { return false; }
        }

        //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        public Int32 Count {
            get { return 0; }
        }

        //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        public Object SyncRoot {
            get { return null; }
        }

        //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1232'"
        public Boolean IsSynchronized {
            get { return false; }
        }
    }
}